package com.qianli.cashmama.trade.openApi.utils;

/**
 * 类说明 日期工具类
 */

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;

public class DateUtil {
    private static Logger logger = LoggerFactory.getLogger(DateUtil.class);

    private static String datePattern = "yyyy-MM-dd";

    private static String timePattern = "HH:mm:ss";

    private static String timeStrPattern = "HHmmss";

    private static String dateTimePattern = "yyyy-MM-dd HH:mm:ss";

    /**
     * Return 缺省的日期格式 (yyyy/MM/dd)
     *
     * @return 在页面中显示的日期格式
     */
    public static String getDatePattern() {
        return datePattern;
    }

    public static String getDateTimePattern(){
        return dateTimePattern;
    }

    /**
     * 根据日期格式，返回日期按datePattern格式转换后的字符串
     *
     * @param aDate 日期对象
     * @return 格式化后的日期的页面显示字符串
     */
    public static final String getDate(Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (aDate != null) {
            df = new SimpleDateFormat(datePattern);
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }

    /**
     * 根据日期格式，返回当前日期指定格式转换后的字符串
     *
     * @param pattern 指定转换格式
     * @return 格式化后的日期字符串
     */
    public static final String getDate(String pattern) {
        Date date = new Date();
        return getDate(date, pattern);
    }

    /**
     * 根据日期格式，返回指定日期指定格式转换后的字符串
     *
     * @param date    日期对象
     * @param pattern 指定转换格式
     * @return 格式化后的日期字符串
     */
    public static final String getDate(Date date, String pattern) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (date != null) {
            df = new SimpleDateFormat(pattern);
            returnValue = df.format(date);
        }
        return (returnValue);
    }

    /**
     * 把传入的日期字符串，转换成指定格式的日期对象
     *
     * @param dateString 日期字符串
     * @param pattern    指定转换格式
     * @return 日期对象
     */
    public static Date getDate(String dateString, String pattern) {
        SimpleDateFormat df = null;
        Date date = new Date();
        if (!StringUtils.isBlank(dateString)) {
            try {
                df = new SimpleDateFormat(pattern);
                date = df.parse(dateString);
            } catch (Exception e) {
                logger.error("getDate error, dateString={}", dateString, e.getMessage());
            }
        }
        return date;
    }

    public static final String getDate(Date date, String pattern, Locale locale) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (date != null) {
            df = new SimpleDateFormat(pattern,locale);
            returnValue = df.format(date);
        }
        return (returnValue);
    }

    public static String getDates(String time, String datePattern) {
        Long timeLong = Long.parseLong(time);
        SimpleDateFormat sdf = new SimpleDateFormat(datePattern);//要转换的时间格式
        Date date;
        try {
            date = sdf.parse(sdf.format(timeLong));
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date getLongDates(String time, String datePattern) {
        Long timeLong = Long.parseLong(time);
        SimpleDateFormat sdf = new SimpleDateFormat(datePattern);//要转换的时间格式
        Date date;
        try {
            date = sdf.parse(sdf.format(timeLong));
            return date;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    public static String getYear() {
        Date date = new Date();
        return getDate(date, "yyyy");
    }

    public static String getDay() {
        Date date = new Date();
        return getDate(date, "dd");
    }

    /**
     * 获取当前时间的小时
     *
     * @return 返回小时
     */
    public static int getHour() {
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取当前时间的分钟
     *
     * @return 返回分钟
     */
    public static int getMinute() {
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 获取当前时间的秒钟
     *
     * @return 返回秒钟
     */
    public static int getSecond() {
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.SECOND);
    }

    /**
     * 获取当前时间的毫秒
     *
     * @return 返回毫秒
     */
    public static long getMillis() {
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    public static String getYears(Date date) {
        return getDate(date, "yyyy");
    }

    public static String getMonths(Date date) {
        return getDate(date, "MM");
    }

    public static String getDays(Date date) {
        return getDate(date, "dd");
    }

    /**
     * 返回小时
     *
     * @param date 日期
     * @return 返回小时
     */
    public static int getHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 返回分钟
     *
     * @param date 日期
     * @return 返回分钟
     */
    public static int getMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 返回秒钟
     *
     * @param date 日期
     * @return 返回秒钟
     */
    public static int getSecond(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.SECOND);
    }

    /**
     * 返回毫秒
     *
     * @param date 日期
     * @return 返回毫秒
     */
    public static long getMillis(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * 按月相加
     *
     * @param date
     * @param month
     * @return
     */
    public static Date addMonth(Date date, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, month);
        return c.getTime();
    }

    /**
     * 按分钟相加
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date addMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        return c.getTime();
    }

    /**
     * 日期相减
     *
     * @param date  日期
     * @param date1 日期
     * @return 返回相减后的日期
     */
    public static int diffDate(Date date, Date date1) {
        date = DateUtil.getDate(DateUtil.getDate(date, "yyyy-MM-dd"), "yyyy-MM-dd");
        date1 = DateUtil.getDate(DateUtil.getDate(date1, "yyyy-MM-dd"), "yyyy-MM-dd");
        return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
    }

    public static int diffHours(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (1000 * 60 * 60));
    }

    public static int diffMinutes(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (1000 * 60));
    }

    public static int diffSeconds(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / 1000);
    }

    public static long diffMillis(Date date, Date date1) {
        return (long) ((getMillis(date) - getMillis(date1)));
    }


    /**
     * 计算两日期之间相差的天数 day1-day2
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int countDays(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return 0;
        }
        long day = (date1.getTime() - date2.getTime()) / (24 * 60 * 60 * 1000);
        return (int) day;
    }

    /**
     * 计算两日期之间相差的天数 day1-day2
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int countDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return 0;
        }
        try {
            date1 = new SimpleDateFormat(datePattern).parse(new SimpleDateFormat(datePattern).format(date1));
            date2 = new SimpleDateFormat(datePattern).parse(new SimpleDateFormat(datePattern).format(date2));
        } catch (ParseException e) {
            logger.error("ParseException error", e);
        }
        long day = (date1.getTime() - date2.getTime()) / (24 * 60 * 60 * 1000);
        return (int) day;
    }

    /**
     * 判断当前日期是星期几
     * <p>
     * 要判断的时间
     *
     * @return dayForWeek 判断结果
     */
    public static int dayForWeek(String dateTimeStr) throws Exception {
        SimpleDateFormat df = new SimpleDateFormat();
        df.applyPattern("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(df.parse(dateTimeStr));
        int dayForWeek = 0;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

    /**
     * 获取某日期是一年中的第几周
     *
     * @param dateTimeStr
     * @return int
     */
    public static int getWeekOfYear(String dateTimeStr) throws Exception {
        SimpleDateFormat df = new SimpleDateFormat();
        df.applyPattern("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(df.parse(dateTimeStr));
        c.setFirstDayOfWeek(Calendar.MONDAY);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 功能: 判断是否是月末
     *
     * @return true月末, false不是月末
     */
    public static boolean isYueMo(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (calendar.get(Calendar.DATE) == calendar
                .getActualMaximum(Calendar.DAY_OF_MONTH)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取月份起始日期
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static String getMinMonthDate(Date date) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 获取月份最后日期
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static String getMaxMonthDate(Date date) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dateFormat.format(calendar.getTime());
    }

    public static String getMaxMonthDate(String dateStr) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = dateFormat.parse(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,
                calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return dateFormat.format(calendar.getTime());
    }

    /**
     * 取得当月天数
     */
    public static int getCurrentMonthDays() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, 1);// 把日期设置为当月第一天
        cal.roll(Calendar.DATE, -1);// 日期回滚一天，也就是最后一天
        int maxDate = cal.get(Calendar.DATE);
        return maxDate;
    }

    public static Date getStartOfDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static Date getEndOfDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);

        return c.getTime();
    }

    public static Date getUTCDate() {
        // 1、取得本地时间：
        Calendar cal = Calendar.getInstance();
        // 2、取得时间偏移量：
        int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
        // 3、取得夏令时差：
        int dstOffset = cal.get(Calendar.DST_OFFSET);
        // 4、从本地时间里扣除这些差量，即可以取得UTC时间：
        cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        // 之后调用cal.get(int x)或cal.getTimeInMillis()方法所取得的时间即是UTC标准时间。
        return new Date(cal.getTimeInMillis());
    }


    /**
     * 当前月的最后 一天
     *
     * @return
     */
    public static Date getMouthLastDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, 1);
        cal.set(Calendar.DATE, 1);//把日期设置为当月第一天
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return cal.getTime();
    }

    public static Date getMouthLastDate() {
        return getMouthLastDate(new Date());
    }


    //月最后一天
    public static String getCalendarMonthLastDay(int month) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        String dayString = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
        return dayString;
    }

    //获取日期属于当月第几周
    public static int getWeekOfMonth(String dateString) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
        return weekOfMonth;
    }

    //获取日期是否属于当月最后一周
    public static boolean isLastWeekOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);

        Date lastDate = getMouthLastDate();
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(lastDate);
        int lastWeekOfMonth = calendar2.get(Calendar.WEEK_OF_MONTH);

        return weekOfMonth == lastWeekOfMonth ? true : false;
    }


    public static String daysBetween(Date mindate, Date maxdate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            mindate = sdf.parse(sdf.format(mindate));
            maxdate = sdf.parse(sdf.format(maxdate));
        } catch (ParseException e) {
            logger.error("ParseException ", e);
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(mindate);
        long time1 = cal.getTimeInMillis();

        cal.setTime(maxdate);
        long time2 = cal.getTimeInMillis();

        long betweenDays = (time2 - time1) / (1000 * 3600 * 24);
        return String.valueOf(betweenDays);
    }


    /**
     * 必须过了生日，才表示满周岁。例如：
     * 2000-10-01出生，当前日期是2000-11-01，未满1周岁，算0周岁！
     * 2000-10-01出生，当前日期是2005-10-01，未满5周岁，算4周岁（生日当天未过完）！
     * 2000-10-01出生，当前日期是2005-10-02，已满5周岁了！
     * 2. 所谓的“算法”
     * 先看“年”，用当前年份减去生日年份得出年龄age
     * 再看“月”，如果当前月份小于生日月份，说明未满周岁age，年龄age需减1；如果当前月份大于等于生日月份，则说明满了周岁age，计算over！
     * 最后“日”，如果月份相等并且当前日小于等于出生日，说明仍未满周岁，年龄age需减1；反之满周岁age，over！
     * <p>
     * 根据生日计算当前周岁数
     */
    public static int getCurrentAge(Date birthday) {
        // 当前时间
        Calendar curr = Calendar.getInstance();
        // 生日
        Calendar born = Calendar.getInstance();
        born.setTime(birthday);
        // 年龄 = 当前年 - 出生年
        int age = curr.get(Calendar.YEAR) - born.get(Calendar.YEAR);
        if (age <= 0) {
            return 0;
        }
        // 如果当前月份小于出生月份: age-1
        // 如果当前月份等于出生月份, 且当前日小于出生日: age-1
        int currMonth = curr.get(Calendar.MONTH);
        int currDay = curr.get(Calendar.DAY_OF_MONTH);
        int bornMonth = born.get(Calendar.MONTH);
        int bornDay = born.get(Calendar.DAY_OF_MONTH);
        if ((currMonth < bornMonth) || (currMonth == bornMonth && currDay <= bornDay)) {
            age--;
        }
        return age < 0 ? 0 : age;
    }


    /**
     * 相差的月数
     *
     * @param start
     * @param end
     * @return
     */
    public static Integer getDiffMonthNum(Date start, Date end) {
        if (Objects.isNull(start) || Objects.isNull(end)) {
            return null;
        }

        if (start.after(end)) {
            Date t = start;
            start = end;
            end = t;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        Calendar temp = Calendar.getInstance();
        temp.setTime(end);
        temp.add(Calendar.DATE, 1);

        int year = endCalendar.get(Calendar.YEAR)
                - startCalendar.get(Calendar.YEAR);
        int month = endCalendar.get(Calendar.MONTH)
                - startCalendar.get(Calendar.MONTH);

        if ((startCalendar.get(Calendar.DATE) == 1)
                && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month + 1;
        } else if ((startCalendar.get(Calendar.DATE) != 1)
                && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month;
        } else if ((startCalendar.get(Calendar.DATE) == 1)
                && (temp.get(Calendar.DATE) != 1)) {
            return year * 12 + month;
        } else {
            return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
        }
    }

    public static int differentDays(Date date1, Date date2) {
        int days = 0;
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2)   //同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)    //闰年
                {
                    timeDistance += 366;
                } else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            days = timeDistance + (day2 - day1);
        } else {
            days = day2 - day1;
        }

        return days;
//        return days > 0 ? days : differentDays(date2, date1);
    }

    /**
     * 判断是不是周末
     *
     * @param date
     * @return
     */
    public static boolean isWeekend(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            return true;
        } else if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    public static String getCreateDate(Date createDate) {
        if (createDate == null) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
        return simpleDateFormat.format(createDate);
    }

    public static void main(String[] args) {
        String a = "2019-01-29";
        String b = "2019-01-06";
        String c = getCreateDate(DateUtil.getDate(a, "yyyy-MM-dd"));

        System.out.println(c);
    }
}
